//==============================================================================
//
//               Copyright (C) 2005  Dick van Oudheusden
//  
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//==============================================================================
// 
//  $Date: 2005-06-01 05:12:47 $ $Revision: 1.7 $
//
//==============================================================================

#include "ofc/DTelNetClient.h"

#include "DTest.h"


//-Network---------------------------------------------------------------------


@interface TelNet : DTelNetClient
{
@private
  int    member;
}

- (BOOL) processOpenNegotiation :(int) who :(int) option :(int) state;
- (BOOL) processResponseNegotiation :(int) who :(int) option :(BOOL) accepted;
- (BOOL) processRequestSubNegotiation :(int) option;
- (BOOL) processSpecialCommand :(unsigned char) command;

@end


@implementation TelNet

- (BOOL) processOpenNegotiation :(int) who :(int) option :(int) state;
{
  BOOL ok = NO;
  
  if (option == 1)  ok = NO;
  if (option == 24) ok = YES; 
  printf("Opening negotiation option %s for %s state %d...\n", [DTelNetClient optionToString :option], (who == DTNC_SERVER ? "Server" : "Client"), state);
  
  return ok;
}

- (BOOL) processResponseNegotiation :(int) who :(int) option :(BOOL) accepted;
{
  printf("Server accepted negotiation option %s for %s state %d...\n", [DTelNetClient optionToString :option], (who == DTNC_SERVER ? "Server" : "Client"), accepted);
  
  return YES;
}

- (BOOL) processRequestSubNegotiation :(int) option
{
  printf("Server request the value for the sub negotiation of option %s..\n", [DTelNetClient optionToString :option]);
  
  if (option == 24) [self respondSubNegotiation :option :"dec-vt100" :9];
  
  return YES;
}

- (BOOL) processSpecialCommand :(unsigned char) command;
{
  printf("Special command: %s received\n", [DTelNetClient commandToString :command]);
  
  return YES;
}
@end


  
void DTelNetClient_test()
{
  TelNet             *client  = [TelNet new];
  DInetSocketAddress *address = [DInetSocketAddress new];
  DURL          *url          = [DURL        new];
  DData         *response     = nil;
  STARTTEST();

  [address host :"localhost" :DTNC_PORT];

  TEST(![client isConnected]);
  
  TEST([client open :address]);
       
  TEST([client isConnected]);
  
  if ([client isConnected])
  {
    char buffer[256];
    
    buffer[0] = EOS;

    [client requestOpenNegotiation :DTNC_SERVER :DTNC_TM   :YES];
    
    do
    {
      BOOL empty = NO;
      BOOL input = NO;
      
      do
      {
        TEST([client sendText :buffer]);

        if (!input)
          response = [client receive];
        
        buffer[0] = EOS;
        
        if (response != nil)
        {
          long i,length;
        
          length = [response length];
      
          empty = (length == 0);
          
          for (i = 0; i < length; i++)
          {
            printf("%c", [response get :i]);
          }
          
          if (length > 0)
          {
            input = ([response get :(length-1)] != '\n');
          }
          
          [response free]; response = nil;
        }
      }
      while (([client pendingRequests]) || (empty) || (!input));
      
      fflush(stdout);
      
      fgets(buffer, sizeof(buffer), stdin);
    }
    while (strncmp(buffer, "exit", 4) != 0);
      
    [client close];
  }
  
  [client  free];
  [url     free];
  [address free];
  
  STOPTEST();
}
